const logger = require('./logger');

class EnvironmentChecker {
  constructor() {
    this.requiredVars = [
      'MONGODB_URI',
      'JWT_SECRET',
      'PORT'
    ];
    
    this.optionalVars = [
      'JWT_EXPIRES_IN',
      'JWT_REFRESH_SECRET',
      'JWT_REFRESH_EXPIRES_IN',
      'NODE_ENV',
      'DEBUG'
    ];
  }

  // 检查所有环境变量
  checkEnvironment() {
    logger.info('Starting environment variables check');
    
    const results = {
      required: {},
      optional: {},
      missing: [],
      warnings: [],
      recommendations: []
    };

    // 检查必需的环境变量
    this.requiredVars.forEach(varName => {
      const value = process.env[varName];
      results.required[varName] = {
        defined: !!value,
        value: value ? this.maskSensitive(varName, value) : null,
        length: value ? value.length : 0
      };

      if (!value) {
        results.missing.push(varName);
        logger.error(`Required environment variable missing: ${varName}`);
      } else {
        logger.debug(`Environment variable OK: ${varName}`);
      }
    });

    // 检查可选的环境变量
    this.optionalVars.forEach(varName => {
      const value = process.env[varName];
      results.optional[varName] = {
        defined: !!value,
        value: value ? this.maskSensitive(varName, value) : null,
        default: this.getDefaultValue(varName)
      };

      if (!value) {
        logger.warn(`Optional environment variable not set: ${varName}, using default: ${this.getDefaultValue(varName)}`);
      }
    });

    // 执行安全检查
    this.performSecurityChecks(results);

    // 生成建议
    this.generateRecommendations(results);

    logger.info('Environment check completed', {
      missingRequired: results.missing.length,
      warningsCount: results.warnings.length,
      recommendationsCount: results.recommendations.length
    });

    return results;
  }

  // 掩码敏感信息
  maskSensitive(varName, value) {
    const sensitiveVars = ['JWT_SECRET', 'JWT_REFRESH_SECRET', 'MONGODB_URI'];
    
    if (sensitiveVars.includes(varName)) {
      if (value.length <= 8) {
        return '*'.repeat(value.length);
      }
      return value.substring(0, 4) + '*'.repeat(value.length - 8) + value.substring(value.length - 4);
    }
    
    return value;
  }

  // 获取默认值
  getDefaultValue(varName) {
    const defaults = {
      'JWT_EXPIRES_IN': '1h',
      'JWT_REFRESH_EXPIRES_IN': '7d',
      'NODE_ENV': 'development',
      'PORT': '5000'
    };
    
    return defaults[varName] || 'undefined';
  }

  // 执行安全检查
  performSecurityChecks(results) {
    // JWT密钥长度检查
    const jwtSecret = process.env.JWT_SECRET;
    if (jwtSecret && jwtSecret.length < 32) {
      results.warnings.push({
        type: 'security',
        message: 'JWT_SECRET should be at least 32 characters long',
        current: jwtSecret.length,
        recommended: 32
      });
    }

    // 生产环境检查
    if (process.env.NODE_ENV === 'production') {
      if (!process.env.JWT_REFRESH_SECRET) {
        results.warnings.push({
          type: 'security',
          message: 'JWT_REFRESH_SECRET should be different from JWT_SECRET in production'
        });
      }

      if (process.env.DEBUG) {
        results.warnings.push({
          type: 'security',
          message: 'DEBUG mode should be disabled in production'
        });
      }
    }

    // MongoDB URI检查
    const mongoUri = process.env.MONGODB_URI;
    if (mongoUri) {
      if (mongoUri.includes('localhost') && process.env.NODE_ENV === 'production') {
        results.warnings.push({
          type: 'configuration',
          message: 'Using localhost MongoDB in production environment'
        });
      }
    }
  }

  // 生成建议
  generateRecommendations(results) {
    if (results.missing.length > 0) {
      results.recommendations.push({
        type: 'critical',
        message: `Create .env file with missing variables: ${results.missing.join(', ')}`
      });
    }

    if (!process.env.JWT_REFRESH_SECRET) {
      results.recommendations.push({
        type: 'security',
        message: 'Add JWT_REFRESH_SECRET for enhanced security'
      });
    }

    if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'development') {
      results.recommendations.push({
        type: 'configuration',
        message: 'Set NODE_ENV to either "development" or "production"'
      });
    }
  }

  // 生成环境配置模板
  generateEnvTemplate() {
    const template = `# 必需的环境变量
MONGODB_URI=mongodb://localhost:27017/travel_app
JWT_SECRET=your-super-secret-jwt-key-at-least-32-characters-long
PORT=5000

# 可选的环境变量
NODE_ENV=development
JWT_EXPIRES_IN=1h
JWT_REFRESH_SECRET=your-refresh-secret-key-different-from-jwt-secret
JWT_REFRESH_EXPIRES_IN=7d

# 调试模式（开发环境）
DEBUG=auth*

# 其他配置
CORS_ORIGIN=http://localhost:3000,http://localhost:8080,http://localhost:8081
`;

    return template;
  }

  // 检查配置文件加载顺序
  checkConfigLoadOrder() {
    const configSources = [];
    
    // 检查 .env 文件
    try {
      require('fs').accessSync('.env');
      configSources.push('.env file found');
    } catch (e) {
      configSources.push('.env file not found');
    }

    // 检查环境变量来源
    const sources = {
      processEnv: Object.keys(process.env).length,
      nodeEnv: process.env.NODE_ENV || 'not set',
      configFiles: configSources
    };

    logger.info('Configuration sources check', sources);
    return sources;
  }

  // 验证关键服务依赖
  async checkDependencies() {
    const results = {
      packages: {},
      versions: {},
      conflicts: []
    };

    try {
      const packageJson = require('../../package.json');
      const criticalPackages = [
        'express',
        'mongoose',
        'jsonwebtoken',
        'bcryptjs',
        'cors',
        'dotenv'
      ];

      criticalPackages.forEach(pkg => {
        if (packageJson.dependencies[pkg]) {
          results.packages[pkg] = {
            version: packageJson.dependencies[pkg],
            installed: true
          };
        } else {
          results.packages[pkg] = {
            version: null,
            installed: false
          };
        }
      });

      // 检查版本兼容性
      this.checkVersionCompatibility(results);

      logger.info('Dependencies check completed', results);
      return results;

    } catch (error) {
      logger.error('Dependencies check failed', error);
      throw error;
    }
  }

  // 检查版本兼容性
  checkVersionCompatibility(results) {
    const knownIssues = {
      'mongoose': {
        '^6.0.0': 'Mongoose 6.x has breaking changes from 5.x',
        '^7.0.0': 'Mongoose 7.x requires Node.js 14+'
      },
      'jsonwebtoken': {
        '^9.0.0': 'JWT 9.x has breaking changes in algorithm handling'
      }
    };

    Object.keys(knownIssues).forEach(pkg => {
      if (results.packages[pkg] && results.packages[pkg].installed) {
        const version = results.packages[pkg].version;
        Object.keys(knownIssues[pkg]).forEach(problematicVersion => {
          if (version.includes(problematicVersion.replace('^', ''))) {
            results.conflicts.push({
              package: pkg,
              version: version,
              issue: knownIssues[pkg][problematicVersion]
            });
          }
        });
      }
    });
  }

  // 系统资源检查
  checkSystemResources() {
    const results = {
      memory: process.memoryUsage(),
      uptime: process.uptime(),
      platform: process.platform,
      nodeVersion: process.version,
      cpuUsage: process.cpuUsage(),
      pid: process.pid
    };

    // 内存使用情况分析
    const memoryMB = {
      rss: Math.round(results.memory.rss / 1024 / 1024),
      heapTotal: Math.round(results.memory.heapTotal / 1024 / 1024),
      heapUsed: Math.round(results.memory.heapUsed / 1024 / 1024),
      external: Math.round(results.memory.external / 1024 / 1024)
    };

    results.memoryMB = memoryMB;

    // 内存警告
    if (memoryMB.heapUsed > 512) {
      logger.warn('High memory usage detected', memoryMB);
    }

    logger.info('System resources check', results);
    return results;
  }

  // 综合环境报告
  async generateEnvironmentReport() {
    try {
      const report = {
        timestamp: new Date(),
        environment: this.checkEnvironment(),
        config: this.checkConfigLoadOrder(),
        dependencies: await this.checkDependencies(),
        system: this.checkSystemResources(),
        template: this.generateEnvTemplate()
      };

      const isHealthy = report.environment.missing.length === 0 && 
                       report.environment.warnings.length === 0;

      report.summary = {
        healthy: isHealthy,
        criticalIssues: report.environment.missing.length,
        warnings: report.environment.warnings.length,
        recommendations: report.environment.recommendations.length
      };

      logger.info('Environment report generated', report.summary);
      return report;

    } catch (error) {
      logger.error('Failed to generate environment report', error);
      throw error;
    }
  }
}

module.exports = new EnvironmentChecker(); 